﻿//-----------------------------------------------------------------------
// <copyright file="DefaultConfigurationProvider.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>23/02/2013</date>
//-----------------------------------------------------------------------

using ConsoleHoster.Common.Utilities;
using System;
using System.IO;

namespace ConsoleHoster.Model.Configuration
{
    internal sealed class DefaultConfigurationProvider : IConfigurationProvider
    {
        public const string SettingKeyTempFolderName = "TempFolderName";
        public const string SettingKeyUpdateServiceEndpointConfigurationName = "UpdateServiceEndpointConfigurationName";
        public const string SettingKeyNumberOfLinesToShowInShowRecentMessagesOnllyMode = "NumberOfLinesToShowInShowRecentMessagesOnllyMode";
        public const string SettingKeyLogOutputFolderName = "LogOutputFolderName";

        public const int DefaultNumberOfLinesToShowInShowRecentMessagesOnlyMode = 50;
        public const string DefaultTempFolderName = "Temp";
        public const string DefaultLogOutputFolderName = "OutputLogs";

        private readonly Func<string, string> settingRetriever;
        private readonly ILogger logger;

        private string updateServiceEndpointConfigurationName;
        private string tempFolderName = DefaultTempFolderName;
        private int numberOfLinesToShowInShowRecentMessagesOnlyMode = DefaultNumberOfLinesToShowInShowRecentMessagesOnlyMode;
        private string logOutputFolderName = DefaultLogOutputFolderName;

        public DefaultConfigurationProvider(Func<string, string> argSettingRetriever, ILogger argLogger)
        {
            ValidationManager.RequireArgumentNotNull(argSettingRetriever, "argSettingRetriever");

            this.logger = new ComponentLogger("DefaultConfigurationProvider", argLogger);
            this.settingRetriever = argSettingRetriever;
            this.RetrieveConfigurationSettings();
        }

        private void RetrieveConfigurationSettings()
        {
            this.TempFolderName = this.GetConfigurationValue(SettingKeyTempFolderName) ?? DefaultTempFolderName;
            this.LogOutputFolderName = this.GetConfigurationValue(SettingKeyLogOutputFolderName) ?? DefaultLogOutputFolderName;
            this.UpdateServiceEndpointConfigurationName = this.GetConfigurationValue(SettingKeyUpdateServiceEndpointConfigurationName);

            string tmpRecentMessagesCountValue = this.GetConfigurationValue(SettingKeyNumberOfLinesToShowInShowRecentMessagesOnllyMode);
            int tmpRecentMessagesCount;
            if (Int32.TryParse(tmpRecentMessagesCountValue, out tmpRecentMessagesCount))
            {
                this.NumberOfLinesToShowInShowRecentMessagesOnlyMode = tmpRecentMessagesCount;
            }
            else
            {
                this.logger.LogWarning(
                    "Unable to parse configuration value for setting: '{0}'. Current value is: '{1}'. Using default value: '{2}' instead.",
                    SettingKeyNumberOfLinesToShowInShowRecentMessagesOnllyMode,
                    tmpRecentMessagesCountValue,
                    DefaultNumberOfLinesToShowInShowRecentMessagesOnlyMode.ToString());
            }
        }

        public string GetConfigurationValue(string argKey)
        {
            return this.settingRetriever(argKey);
        }

        public string TempFolderName
        {
            get
            {
                return this.tempFolderName;
            }
            private set
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("TempFolderName cannot be empty or null");
                }

                this.tempFolderName = Path.Combine(Directory.GetCurrentDirectory(), value);
            }
        }

        public string LogOutputFolderName
        {
            get
            {
                return this.logOutputFolderName;
            }
            set
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("LogOutputFolderName cannot be empty or null");
                }

                this.logOutputFolderName = Path.Combine(Directory.GetCurrentDirectory(), value);
            }
        }

        public string UpdateServiceEndpointConfigurationName
        {
            get
            {
                return this.updateServiceEndpointConfigurationName;
            }
            private set
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("UpdateServiceEndpoingConfigurationName cannot be empty or null");
                }

                this.updateServiceEndpointConfigurationName = value;
            }
        }

        public int NumberOfLinesToShowInShowRecentMessagesOnlyMode
        {
            get
            {
                return this.numberOfLinesToShowInShowRecentMessagesOnlyMode;
            }
            private set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException("value");
                }

                this.numberOfLinesToShowInShowRecentMessagesOnlyMode = value;
            }
        }
    }
}
